package com.jianglin.state2.util;

import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 对象工具类
 *
 * @author violetfreesia
 * @since 2020-12-6
 */
@Slf4j
public class BeanUtil {
    /**
     * 类型转换函数，可以将两个无关的类型进行转换，转换的方式是相同属性赋值
     * 注意这里转换的时候采用的是浅拷贝
     *
     * @param sourceObj 原对象
     * @param sClass    原对象的CLass对象
     * @param tClass    目标对象的CLass对象
     * @param <S>       原类
     * @param <T>       目标类
     * @return 返回目标对象
     */
    public static <S, T> T convert(S sourceObj, Class<S> sClass, Class<T> tClass) {
        T target = null;
        try {
            target = tClass.getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            log.error("目标类没有无参构造器");
        }
        List<String> tFields = Arrays.stream(tClass.getDeclaredFields())
                .map(Field::getName)
                .collect(Collectors.toList());
        T finalTarget = target;
        Arrays.stream(sClass.getDeclaredFields())
                .forEach(sField -> {
                    if (tFields.contains(sField.getName())) {
                        try {
                            char[] chars = sField.getName().toCharArray();
                            chars[0] -= 32;
                            String fieldName = String.valueOf(chars);
                            Method tMethod = tClass.getMethod("set" + fieldName, sField.getType());
                            Method sMethod = sClass.getMethod("get" + fieldName);
                            tMethod.invoke(finalTarget, sMethod.invoke(sourceObj));
                        } catch (Exception e) {
                            log.error("没有获取当相应的get/set方法:" + e.getMessage());
                        }
                    }
                });
        return finalTarget;
    }
}
